# -*- coding: utf-8 -*-

# from PyQt4                              import QtCore
# from utils.utils                        import getExeFromPath

from UI.UI_launch_config_dial           import Ui_manage_launch_config_dial
from new_config_dial                    import NewConfigDial
from PyQt4                              import QtGui
from constants.constants                import TABLE_LAUNCH_CONFIGURATIONS
from constants.constants                import TABLE_NAME_CONFIGURATIONS
from constants.constants                import TABLE_ACTION_LAUNCH_REL
from utils.utils                        import getIconPathFromExe
from utils.utils                        import askForm
from utils.utils                        import setTheme
import os

class CustomImportDial(QtGui.QDialog, Ui_manage_launch_config_dial):
    def __init__(self, parent, headers, rows):
        super(CustomImportDial, self).__init__(parent=parent)
        self.headers = headers
        self.rows = rows
        self.setupUi(self)
        self.initFields()
        self.setEvents()
        self.setContextMenus()
        setTheme(self)
            
    def initFields(self,):
        confObjects = self.dbInst.getRowsTable(TABLE_NAME_CONFIGURATIONS, fields=['config_value'], filtersList=[('config_name', '=', 'LAUNCH_CONFIG_HEADERS_ORDER')])
        self.config_headers_order = eval(confObjects[0].config_value)
        self.localLaunchObjs = []
        self.allLaunchObjs = []
        self.tableWidget_all.setColumnCount(len(self.config_headers_order))
        self.tableWidget_local.setColumnCount(len(self.config_headers_order))
        self.tableWidget_all.setHorizontalHeaderLabels(self.config_headers_order)
        self.tableWidget_local.setHorizontalHeaderLabels(self.config_headers_order)
        self.tableWidget_all.horizontalHeader().setStretchLastSection(True)
        self.tableWidget_local.horizontalHeader().setStretchLastSection(True)
        self.tableWidget_all.horizontalHeader().setResizeMode(QtGui.QHeaderView.ResizeToContents)
        self.tableWidget_local.horizontalHeader().setResizeMode(QtGui.QHeaderView.ResizeToContents)

    def setEvents(self):
        self.pushButton_add_config.clicked.connect(self.moveLeft)
        self.pushButton_remove_config.clicked.connect(self.moveRight)
        self.buttonBox.accepted.connect(self.acceptAskForm)
        self.buttonBox.rejected.connect(self.rejectAskForm)
        self.tableWidget_all.itemSelectionChanged .connect(self.nodeClickedAll)
        self.tableWidget_local.itemSelectionChanged .connect(self.nodeClickedLocal)
        self.horizontalSlider.sliderMoved.connect(self.changeTransparency)
        self.lineEdit_search_all.textChanged.connect(self.changedSearchAll)
        self.lineEdit_search_local.textChanged.connect(self.changedSearchLocal)
        
    def changedSearchAll(self, newVal):
        self.setCommonFilter(newVal, self.allLaunchObjs, self.tableWidget_all)
    
    def changedSearchLocal(self, newVal):
        self.setCommonFilter(newVal, self.localLaunchObjs, self.tableWidget_local)
        
    def setCommonFilter(self, newVal, objList, tableWidget):
        revList = []
        for obj in objList:
            if str(newVal).upper() in str(obj.name).upper():
                revList.append(obj)
        tableWidget.clear()
        tableWidget.setRowCount(0)
        self.setRowsToTableWidget(tableWidget, revList)
        
    def filterAllAvaibleConfig(self, alreadyUsedObjs, allAvaibleObjs):
        outObjs = []
        for allAvaible in allAvaibleObjs:
            found = False
            for usedObj in alreadyUsedObjs:
                if allAvaible.id == usedObj.id:
                    found = True
                    break
            if not found:
                outObjs.append(allAvaible)
        return outObjs
        
    def nodeClickedAll(self):
        self.buttonsToggle(True)
    
    def nodeClickedLocal(self):
        self.buttonsToggle(False)
    
    def buttonsToggle(self, val):
        self.pushButton_add_config.setEnabled(val)
        self.pushButton_add_config.setDefault(val)
        self.pushButton_remove_config.setEnabled(not val)
        self.pushButton_remove_config.setDefault(not val)
        
    def moveRight(self):
        rowIndexesSelected = self.getSelectedIndexesLocalConfig()
        tupleList = self.commonMove(self.tableWidget_local, self.tableWidget_all, rowIndexesSelected, 'toRemove', 'toAdd')
        self.commonObjUpdate(tupleList, self.localLaunchObjs, self.allLaunchObjs)
        self.tableWidget_local.setColumnCount(len(self.config_headers_order))
        self.tableWidget_local.setHorizontalHeaderLabels(self.config_headers_order)

    def moveLeft(self):
        rowIndexesSelected = self.getSelectedIndexesAllConfig()
        tupleList = self.commonMove(self.tableWidget_all, self.tableWidget_local, rowIndexesSelected, 'toAdd', 'toRemove')
        self.commonObjUpdate(tupleList, self.allLaunchObjs, self.localLaunchObjs)
        self.tableWidget_all.setColumnCount(len(self.config_headers_order))
        self.tableWidget_all.setHorizontalHeaderLabels(self.config_headers_order)
        
    def commonObjUpdate(self, tupleList, fromList, toList):
        toRemove = []
        for exe_path, name, description in tupleList:
            description
            for obj in fromList:
                if obj.name == name and obj.exe_path == exe_path:
                    toList.append(obj)
        for obj in toRemove:
            fromList.remove(obj)
         
    def commonMove(self, tableFrom, tableTo, rowIndexesSelected, dictKey, oppositeKey):
        outRowObjs = []
        newRowCount = tableTo.rowCount()
        for rowCount in rowIndexesSelected:
            tableTo.setRowCount(newRowCount+1)
            exe_path    = tableFrom.item(rowCount,self.config_headers_order.index('exe_path')).text()
            name        = tableFrom.item(rowCount,self.config_headers_order.index('name')).text()
            description = tableFrom.item(rowCount,self.config_headers_order.index('description')).text()
            tupleToSave = (exe_path,name,description)
            outRowObjs.append(tupleToSave)
            if tupleToSave in self.toUpdateDict[oppositeKey]:
                self.toUpdateDict[oppositeKey].remove(tupleToSave)
            else:
                self.toUpdateDict[dictKey].append(tupleToSave)
            for colNum in range(0,tableFrom.columnCount()):
                tableTo.setItem(newRowCount, colNum, QtGui.QTableWidgetItem(tableFrom.item(rowCount,colNum) or ''))
            newRowCount = newRowCount+1
        self.removeRowsFromTable(tableFrom, rowIndexesSelected)
        return outRowObjs
    
    def removeRowsFromTable(self, table, rowIndexesSelected):
        rowIndexesSelected.sort()
        rowIndexesSelected.reverse()
        for selectedIndex in rowIndexesSelected:
            table.removeRow(selectedIndex)
            #table.setRowCount(table.rowCount()-1)
        
    def setRowsToTableWidget(self, tableWidget, rowsTable):
        outExeList = []
        for rowObj in rowsTable:
            currentRowCount = tableWidget.rowCount()
            tableWidget.setRowCount(currentRowCount+1)
            iconPath = getIconPathFromExe(rowObj.exe_path)
            outExeList.append(rowObj)
            iconObj = QtGui.QIcon(iconPath)
            tableWidget.setItem(currentRowCount, self.config_headers_order.index('exe_path'), QtGui.QTableWidgetItem(iconObj,rowObj.exe_path))
            tableWidget.setItem(currentRowCount, self.config_headers_order.index('name'), QtGui.QTableWidgetItem(rowObj.name))
            tableWidget.setItem(currentRowCount, self.config_headers_order.index('description'), QtGui.QTableWidgetItem(rowObj.description))
        return outExeList
            
    def setLocalLaunch(self,avaibleRelations):
        launchIds = []
        for relationObj in avaibleRelations:
            launchIds.append(relationObj.launch_id)
        rowsTable = self.dbInst.getRowsTable(TABLE_LAUNCH_CONFIGURATIONS,[],[('id','in',launchIds)])
        self.localLaunchObjs = self.setRowsToTableWidget(self.tableWidget_local, rowsTable)
        return rowsTable
        
    def setContextMenus(self):
        self.tableWidget_local.contextMenuEvent = self.menuTreeLaunchLocal
        self.tableWidget_all.contextMenuEvent   = self.menuTreeLaunchAll
        
    def menuTreeLaunchLocal(self, event):
        pass
    
    def menuTreeLaunchAll(self, event):
        contexMenu=QtGui.QMenu(self)
        
        addConfig         = QtGui.QAction("Create Launch configurations", self, triggered=self._createOneAllConfig)
        deleteConfig      = QtGui.QAction("Delete Launch configurations", self, triggered=self._deleteOneAllConfig)
        
        modelIndexForPos = self.tableWidget_all.indexAt(event.pos())
        if not modelIndexForPos.isValid():
            self.tableWidget_all.clearSelection()
            contexMenu.exec_(event.globalPos())
        contexMenu.addAction(addConfig)
        contexMenu.addAction(deleteConfig)
        
        contexMenu.exec_(event.globalPos())
        del(contexMenu)
    
    def _createOneAllConfig(self):
        dial = NewConfigDial(self.exeList, parent=self)

        if dial.exec_() == QtGui.QDialog.Accepted:
            customFlag = dial.radioButton_custom.isChecked()
            pathsToAdd = []
            toWriteList = []
            if customFlag:
                pathsToAdd.append(dial.lineEdit_out_path.text())
            else:
                indexes = dial.listWidget.selectedIndexes()
                for index in indexes:
                    pathsToAdd.append(index.data().toString())
            for pathToAdd in pathsToAdd:
                toWrite = {}
                currentRowCount = self.tableWidget_all.rowCount()
                self.tableWidget_all.setRowCount(currentRowCount+1)
                iconPath = getIconPathFromExe(pathToAdd)
                iconObj = QtGui.QIcon(iconPath)
                self.tableWidget_all.setItem(currentRowCount, self.config_headers_order.index('exe_path'), QtGui.QTableWidgetItem(iconObj,pathToAdd))
                fileName = os.path.basename(str(pathToAdd)).split('.')[0]
                toWrite['name']     = str(fileName)
                toWrite['exe_path'] = str(pathToAdd)
                toWriteList.append(toWrite)
                self.tableWidget_all.setItem(currentRowCount, self.config_headers_order.index('name'), QtGui.QTableWidgetItem(fileName))
            #saveThread = WriteToDbThread(tableName=TABLE_LAUNCH_CONFIGURATIONS,rowsToWrite=toWriteList,dbInst=self.dbInst)
            #saveThread.start()
            self.writeLaunchConfigs(toWriteList)
            
    def writeLaunchConfigs(self, toWriteList):
        for rowDict in toWriteList:
            res = self.dbInst.getRowsTable(TABLE_LAUNCH_CONFIGURATIONS, ['id','name'],[('exe_path','=',rowDict.get('exe_path'))])
            if not res:
                self.dbInst.writeRow(rowDict,TABLE_LAUNCH_CONFIGURATIONS)
            elif res[0].name != rowDict.get('name'):
                form = askForm('Name "%s" is already saved for exe path "%s", overwrite the record?'%(rowDict.get('name'),rowDict.get('exe_path')), 'Save')
                if form.exec_():
                    self.dbInst.updateRow(rowDict, TABLE_LAUNCH_CONFIGURATIONS, [('id','=',res[0])])
    
    def _deleteOneAllConfig(self):
        form = askForm('Are you show you want to delete these configurations?', 'Delete')
        if form.exec_():
            rowIndexesSelected = self.getSelectedIndexesAllConfig()
            rowIndexesSelected.sort()
            rowIndexesSelected.reverse()
            for selectedIndex in rowIndexesSelected:
                filePath = self.tableWidget_all.item(selectedIndex,0).data(0).toString()
                name = self.tableWidget_all.item(selectedIndex,1).data(0).toString()
                dbRows = self.dbInst.getRowsTable(TABLE_LAUNCH_CONFIGURATIONS,['id'],[('name','=',name),('exe_path','=',filePath)])
                for rowObj in dbRows:
                    self.dbInst.deleteRowdb(rowObj.id, TABLE_LAUNCH_CONFIGURATIONS)
                self.tableWidget_all.removeRow(selectedIndex)
        
    def getCommonSelectedRows(self, tableWidget):
        if tableWidget:
            indexes = tableWidget.selectedIndexes()
            rowIndexesSelected = []
            for index in indexes:
                if index.row() not in rowIndexesSelected:
                    rowIndexesSelected.append(index.row())
            return rowIndexesSelected
        
    def getSelectedIndexesAllConfig(self):
        return self.getCommonSelectedRows(self.tableWidget_all)

    def getSelectedIndexesLocalConfig(self):
        return self.getCommonSelectedRows(self.tableWidget_local)

    def changeTransparency(self, value=0):
        outVal = 100 - value
        self.setWindowOpacity(outVal/100.)
        
    def acceptAskForm(self):
        self.accept()
        
    def rejectAskForm(self):
        self.reject()
